package common

import (
	"bytes"
	"crypto/cipher"
	"crypto/des"
	"encoding/base64"
	"errors"
)

var HyCBCKey = "Hy8fe6fe"

// 加密
func MsgEncCBCEncrypt(plaintext []byte) (string, error) {
	block, err := des.NewCipher([]byte(HyCBCKey))
	if err != nil {
		return "", err
	}
	plaintext = pad(plaintext, block.BlockSize())
	mode := cipher.NewCBCEncrypter(block, []byte(HyCBCKey))
	crypted := make([]byte, len(plaintext))
	mode.CryptBlocks(crypted, plaintext)

	return base64.RawURLEncoding.EncodeToString(crypted), nil
}

// 解密
func MsgDecCBCDecrypt(ciphertexts string) ([]byte, error) {
	ciphertext, err := base64.RawURLEncoding.DecodeString(ciphertexts)
	if err != nil {
		return nil, err
	}
	block, err := des.NewCipher([]byte(HyCBCKey))
	if err != nil {
		return nil, err
	}
	if len(ciphertext)%block.BlockSize() != 0 {
		return nil, errors.New("ciphertext is not a multiple of the block size")
	}
	mode := cipher.NewCBCDecrypter(block, []byte(HyCBCKey))
	plaintext := make([]byte, len(ciphertext))
	mode.CryptBlocks(plaintext, ciphertext)
	plaintext = unpad(plaintext, block.BlockSize())
	return plaintext, nil
}

func pad(buf []byte, blockSize int) []byte {
	padding := blockSize - (len(buf) % blockSize)
	padtext := bytes.Repeat([]byte{byte(padding)}, padding)
	return append(buf, padtext...)
}

func unpad(buf []byte, blockSize int) []byte {
	if len(buf)%blockSize != 0 {
		return nil
	}
	padding := int(buf[len(buf)-1])
	return buf[:len(buf)-padding]
}
